package com.yao.service.impl;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntBinaryOperator;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static java.util.Comparator.comparing;

import com.yao.entity.Apple;
import com.yao.service.ApplePredicate;
import com.yao.service.BufferedReaderProcessor;

public class AppleServiceImpl {

	/**
	 * 筛选重量大于150的绿色苹果
	 */
	public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {

		List<Apple> result = new ArrayList<Apple>();

		for (Apple apple : inventory) {

			if (p.test(apple)) {
				result.add(apple);
			}

		}

		return result;
	}

	/**
	 * 方法引用排序
	 */
	public static void sort(List<Apple> inventory) {
		inventory.forEach(System.out::println);
		inventory.sort(Comparator.comparing(Apple::getWeight));
		System.out.println();
		inventory.forEach(System.out::println);
	}

	public static void main(String[] args) throws IOException {

		List<Apple> inventory = Arrays.asList(new Apple("green", 80), new Apple("red", 120), new Apple("yellow", 115),
				new Apple("green", 155));

		sort(inventory);
		List<Apple> apples = filterApples(inventory, new ApplePredicate() {

			@Override
			public boolean test(Apple apple) {
				return "red".equalsIgnoreCase(apple.getColor());
			}
		});
		

		String s1 = String.format("选择红色苹果有 [%s]个", apples.size());

		System.out.println(s1);

		System.out.println("-----------使用Lambda表达式---------------");

		apples = filterApples(inventory,
				apple -> "green".equalsIgnoreCase(apple.getColor()) && apple.getWeight() > 100);

		s1 = String.format("选择重量大于100的绿色苹果有 [%s]个", apples.size());

		System.out.println(s1);

		System.out.println("-----------使用泛型和Lambda表达式---------------");

		List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

		List<Integer> eventNumbers = filter(numbers, (Integer i) -> i % 2 == 0);

		s1 = String.format("能被2整除的正整数有 [%s]个\n", eventNumbers.size());

		System.out.println(s1);

		// sort排序
		inventory.sort(new Comparator<Apple>() {

			@Override
			public int compare(Apple o1, Apple o2) {
				return o1.getWeight().compareTo(o2.getWeight());
			}
		});

		System.out.println("根据重量普通排序结果为(轻到重)：");
		inventory.forEach((Apple a) -> System.out.println(a));

		// Lambda 表达式sort排序
		inventory.sort((Apple a1, Apple a2) -> a2.getWeight().compareTo(a1.getWeight()));

		// 方法引用 表达式sort排序,根据重量排序，重量一样根据颜色排序
		inventory.sort(comparing(Apple::getWeight)
				.reversed()
				.thenComparing(Apple::getColor));

		System.out.println("\n根据重量Lambda排序结果为(重到轻)：");
		inventory.forEach((Apple a) -> System.out.println(a));

		Thread t = new Thread(() -> System.out.println("\nLambda 线程输入 hello world~"));
		t.run();

		System.out.println("-----------processFile和Lambda表达式，循环读取文件---------------");

		System.out.println(processFile((BufferedReader br) -> {
			// 循环读取文件
			StringBuffer sb = new StringBuffer();

			String s = "";

			while ((s = br.readLine()) != null) {
				sb.append(s + "\n");
			}

			return sb.toString();

		}));

		System.out.println("-----------forEach和Lambda表达式，访问对象---------------");

		forEach(numbers, (Integer i) -> System.out.println(i));

		System.out.println("-----------map和Lambda表达式，映射关系---------------");

		List<Integer> l = map(Arrays.asList("lambdas", "in", "action"), (String s) -> s.length());

		l.forEach((Integer i) -> System.out.println("字符长度为：" + i));

		System.out.println(get(() -> new Apple("green", 80)));

		System.out.println(mul(10, 20, (int a, int b) -> a / b));

		System.out.println(isEmpty("", (String s) -> "".equals(s)));

		System.out.println("----------------------黄金分割-------------------------");

		Integer a = 3;
		int b = 3;

		System.out.println("a == b ?" + (a == b));
		System.out.println("a == b ?" + (a == new Integer(b)));

		String c = "123";
		String d = "123";

		System.out.println("c == d ?" + (c == d));

		String e = c;

		c = "333";

		System.out.println(e);
		
		
		Predicate<Apple> redApple = app -> app.getColor().equalsIgnoreCase("red");
		Predicate<Apple> notRedApple = redApple.negate();
		
		System.out.println();
		filter(inventory, redApple).forEach(System.out::println);
		System.out.println();
		filter(inventory, notRedApple).forEach(System.out::println);
	}

	public static <T> boolean isEmpty(T t, Predicate<T> p) {
		return p.test(t);
	}

	/**
	 * 筛选，布尔表达式
	 */
	public static <T> List<T> filter(List<T> list, Predicate<T> p) {

		List<T> result = new ArrayList<T>();

		for (T t : list) {

			if (p.test(t)) {
				result.add(t);
			}
		}

		return result;
	}

	/**
	 * 从一个对象中选择/提取
	 */
	public static <T> void forEach(List<T> list, Consumer<T> c) {

		for (T t : list) {
			c.accept(t);
		}

	}

	public static <T, R> List<R> map(List<T> list, Function<T, R> f) {

		List<R> result = new ArrayList<R>();

		for (T t : list) {

			result.add(f.apply(t));
		}

		return result;

	}

	public static String processFile(BufferedReaderProcessor p) throws IOException {
		try {
			BufferedReader br = new BufferedReader(new FileReader("README.md"));
			return p.process(br);
		} finally {
		}
	}

	/**
	 * 创建对象
	 */
	public static <T> T get(Supplier<T> s) {
		return s.get();
	}

	/**
	 * 合并两个值
	 */
	public static int mul(int i, int j, IntBinaryOperator ib) {
		return ib.applyAsInt(i, j);
	}
}
